home *** CD-ROM | disk | FTP | other *** search
- /* nothing like the original from
- * from Dale Schumacher's dLibs
- */
-
- /* 5/26/93 sb -- Modified for HSC to account for the possibility that
- * size * count >= 64K.
- */
-
- #include <stddef.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <limits.h>
- #include <assert.h>
- #include <string.h>
- #include "lib.h"
-
- extern short __FRW_BIN__;
-
- size_t fread(_data, size, count, fp)
- void *_data;
- size_t size;
- size_t count;
- register FILE *fp;
- {
- #ifdef __SOZOBON__
- register unsigned long n;
- #else
- register size_t n;
- #endif
- register long l, cnt;
- register unsigned int f;
- char *data=_data;
- char *ptr;
-
- assert((data != NULL));
- assert((size != 0));
-
- f = fp->_flag;
- if(f & _IORW) f = (fp->_flag |= _IOREAD);
- if(!(f & _IOREAD) || (f & (_IOERR | _IOEOF)))
- return(0);
-
- l = 0;
- #ifdef __SOZOBON__
- n = (unsigned long)count * size;
- #else
- n = count * size;
- #endif
- #if 0
- if(fflush(fp)) /* re-sync file pointers */
- return 0;
- #endif
- assert((n <= (size_t)LONG_MAX));
- if( (f&_IOBIN) || __FRW_BIN__ ) {
- again:
- if((cnt = fp->_cnt) > 0)
- {
- cnt = (cnt < n) ? cnt : n;
- #ifdef __SOZOBON__
- _bcopy(fp->_ptr, data, cnt);
- #else
- bcopy(fp->_ptr, data, cnt);
- #endif
- fp->_cnt -= cnt;
- fp->_ptr += cnt;
- l += cnt;
- data = data + cnt;
- n -= cnt;
- }
- /* n == how much more */
- if(n > 0)
- {
- if(n < fp->_bsiz)
- { /* read in fp->_bsiz bytes into fp->_base and do it again */
- fp->_ptr = fp->_base;
- if((cnt = _read(fp->_file, fp->_base, (unsigned long)fp->_bsiz)) <= 0)
- { /* EOF or error */
- fp->_flag |= ((cnt == 0) ? _IOEOF : _IOERR);
- goto ret;
- }
- fp->_cnt = cnt;
- goto again;
- }
- else
- while (n > 0)
- { /* read in n bytes into data */
- if((cnt = _read(fp->_file, data, (unsigned long)n)) <= 0)
- { /* EOF or error */
- fp->_flag |= ((cnt == 0) ? _IOEOF : _IOERR);
- goto ret;
- }
- l += cnt;
- data = data + cnt;
- n -= cnt;
- }
- }
- } else {
- while( n>0 ) {
- if( (cnt=fp->_cnt)>0 ) {
- ptr=(char*)fp->_ptr;
- while( n>0 && cnt>0 ) {
- if( *ptr!='\r' ) {
- *data++=*ptr++;
- cnt--;
- n--;
- l++;
- } else {
- ptr++;
- cnt--;
- }
- }
- fp->_cnt=cnt;
- fp->_ptr=(unsigned char*)ptr;
- }
- if( n==0 ) break; /* done */
- /* wanna have n more bytes */
- if( n<fp->_bsiz ) {
- /* read in fp->_bsiz bytes into fp->_base and do it again */
- fp->_ptr = fp->_base;
- if((cnt = _read(fp->_file, fp->_base, (unsigned long)fp->_bsiz)) <= 0)
- { /* EOF or error */
- fp->_flag |= ((cnt == 0) ? _IOEOF : _IOERR);
- goto ret;
- }
- fp->_cnt = cnt;
- } else {
- /* read in n bytes into data */
- if((cnt = _read(fp->_file, data, (unsigned long)n)) <= 0)
- { /* EOF or error */
- fp->_flag |= ((cnt == 0) ? _IOEOF : _IOERR);
- goto ret;
- }
- /* Quickly move to first CR */
- ptr = memchr (data, '\r', cnt);
- if (ptr == NULL)
- ptr = data + cnt;
- cnt -= ptr - data;
- n -= ptr - data;
- l += ptr - data;
- data = ptr;
- while( cnt>0 ) {
- if( *ptr!='\r' ) {
- *data++=*ptr++;
- cnt--;
- n--;
- l++;
- } else {
- ptr++;
- cnt--;
- }
- }
- }
- }
- }
-
- ret:
- #ifdef __SOZOBON__
- return((l > 0) ? ((size_t)((unsigned long)l / size)) : 0);
- #else
- return((l > 0) ? ((size_t)l / size) : 0);
- #endif
- }
-